package com.ufm.security.support;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.TextEscapeUtils;

import com.google.code.kaptcha.Constants;
  
/**
 * @author Wiker Yong Email:<a href="mailto:wikeryong@gmail.com">wikeryong@gmail.com</a>
 * @date 2013-7-15 下午5:56:54
 * @version 1.0-SNAPSHOT
 */
public class VolidateAuthCodeUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{  
  
    private boolean postOnly = true;  
    private boolean allowEmptyValidateCode = false;  
    private String sessionvalidateCodeField = DEFAULT_SESSION_VALIDATE_CODE_FIELD;  
    private String validateCodeParameter = DEFAULT_VALIDATE_CODE_PARAMETER;  
    public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";  
    // session中保存的验证码  
    public static final String DEFAULT_SESSION_VALIDATE_CODE_FIELD = Constants.KAPTCHA_SESSION_KEY;  
    // 输入的验证码  
    public static final String DEFAULT_VALIDATE_CODE_PARAMETER = "code";  
    public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username";
    public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password";
    private FilterInvocationSecurityMetadataSource securityMetadataSource;
    
    @Override  
    public Authentication attemptAuthentication(HttpServletRequest request,  
            HttpServletResponse response) throws AuthenticationException {  
        if (postOnly && !request.getMethod().equals("POST")) {  
            throw new AuthenticationServiceException(  
                    "Authentication method not supported: "+ request.getMethod());  
        }  
        String usernameHidden = request.getParameter("usernameHidden");  
        String passwordHidden = request.getParameter("passwordHidden"); 
        String username = request.getParameter("username");  

        String password = request.getParameter("password");  
        if("guest".equals(usernameHidden)){
        	username= usernameHidden.trim();
        	password = passwordHidden;
        }else{
        username = username.trim();  
        }
        
        UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);  
  
        // Place the last username attempted into HttpSession for views  
        HttpSession session = request.getSession(false);  
  
        if (session != null || getAllowSessionCreation()) {  
            request.getSession().setAttribute(  
                    SPRING_SECURITY_LAST_USERNAME_KEY,  
                    TextEscapeUtils.escapeEntities(username));  
        }  
  
        // Allow subclasses to set the "details" property  
        setDetails(request, authRequest);  
        // check validate code  
        if (!isAllowEmptyValidateCode()&& !"guest".equals(username))  
            checkValidateCode(request);  
        // 根据用户和密码查询  
         
        return this.getAuthenticationManager().authenticate(authRequest);  
    }  
  
    /** 
     *  
     * <li>比较session中的验证码和用户输入的验证码是否相等</li> 
     *  
     */  
    protected void checkValidateCode(HttpServletRequest request) {  
        String sessionValidateCode = obtainSessionValidateCode(request);  
        String validateCodeParameter = obtainValidateCodeParameter(request);  
        if (validateCodeParameter==""||!sessionValidateCode.equalsIgnoreCase(validateCodeParameter)) {  
        	//request.setAttribute("msg", "code");
        	throw new AuthenticationServiceException("验证码错误！"); 
        }  
    }  
  
    private String obtainValidateCodeParameter(HttpServletRequest request) {  
        return request.getParameter(validateCodeParameter);  
    }  
  
    protected String obtainSessionValidateCode(HttpServletRequest request) {  
        Object obj = request.getSession().getAttribute(sessionvalidateCodeField);  
        return null == obj ? "" : obj.toString();  
    }  
  
    public boolean isPostOnly() {  
        return postOnly;  
    }  
  
    @Override  
    public void setPostOnly(boolean postOnly) {  
        this.postOnly = postOnly;  
    }  
  
    public String getValidateCodeName() {  
        return sessionvalidateCodeField;  
    }  
  
    public void setValidateCodeName(String validateCodeName) {  
        this.sessionvalidateCodeField = validateCodeName;  
    }  
  
    public boolean isAllowEmptyValidateCode() {  
        return allowEmptyValidateCode;  
    }  
  
    public void setAllowEmptyValidateCode(boolean allowEmptyValidateCode) {  
        this.allowEmptyValidateCode = allowEmptyValidateCode;  
    }

	public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {
		return securityMetadataSource;
	}

	public void setSecurityMetadataSource(
			FilterInvocationSecurityMetadataSource securityMetadataSource) {
		this.securityMetadataSource = securityMetadataSource;
	}  
    
    
} 